package com.example.demo.service.impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo.common.utils.IdUtils;
import com.example.demo.entity.websocket.Message;
import com.example.demo.entity.websocket.MessageForm;
import com.example.demo.entity.websocket.User;
import com.example.demo.entity.websocket.WebSocket;
import com.example.demo.exception.BusinessException;
import com.example.demo.mapper.MessageMapper;
import com.example.demo.mapper.UserMapper;
import com.example.demo.service.MessageService;
import com.example.demo.utils.WebSocketUtil;
import java.sql.Connection;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
public class MessageServiceImpl implements MessageService {

    @Resource
    private WebSocketUtil webSocketUtil;
    @Resource
    private UserMapper userMapper;
    @Resource
    private MessageMapper messageMapper;
    // 限制聊天记录数量
    final Integer limitMessagesLength = 6000;
    // 限制用户数量
    final Integer limitUserLength = 300;

    @Override
    // 获取未读的接收信息
    public Integer findNoReadMessageLength(String userId)  {
        try {

            Integer totol = 0;
            if(Validator.isEmpty(userId)) throw  new BusinessException("用户编号不能为空!");
            User user = userMapper.selectById(userId);
            if(Validator.isEmpty(user)) throw  new BusinessException("用户编号:" + userId + "不存在!");
            // 为防止发送人特别多导致信息未获取，这里多设置一些拿信息数据
            QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();
            messageQueryWrapper.lambda().eq(Message::getReceiveUser,userId);
            messageQueryWrapper.lambda().last("limit "+limitMessagesLength);
            List<Message> messages = messageMapper.selectList(messageQueryWrapper);
            Map<String, List<Message>> messageBySendUserMap = messages.stream()
                    .collect(Collectors.groupingBy(Message::getSendUser));
            for (String sendUser : messageBySendUserMap.keySet()) {
                List<Message> receiveMessageList = messageBySendUserMap.get(sendUser);
                Integer noReadSize = receiveMessageList.stream().filter(o -> "0".equals(o.getIsRead()))
                        .collect(Collectors.toList()).size();
                totol += noReadSize;
            }
            return totol;
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED, timeout = 30, rollbackFor = Exception.class)
    // 发送信息的逻辑
    public void sendMessage(Message message){
        try {
            if(Validator.isEmpty(message.getSendUser())) throw  new BusinessException("发送用户不能为空!");
            if(Validator.isEmpty(message.getReceiveUser())) throw  new BusinessException("接收用户不能为空!");
            if(Validator.isEmpty(message.getContent())) throw  new BusinessException("发送信息不能为空!");
            User sendUser = userMapper.selectById(message.getSendUser());
            if(Validator.isEmpty(sendUser)) throw  new BusinessException("发送用户不存在,发送信息失败!");
            if(sendUser.getStatus() != 1) throw  new BusinessException("状态已冻结,无法发送信息!");
            User receiveUser = userMapper.selectById(message.getReceiveUser());
            if(Validator.isEmpty(receiveUser)) throw  new BusinessException("接收用户不存在,发送信息失败!");
            if(receiveUser.getStatus() != 1) throw  new BusinessException("接收用户:" + message.getReceiveUser() + "状态已冻结,无法接收信息!");
            message.setId(IdUtils.getId());
            message.setHandle(UUID.randomUUID().toString());
            message.setIsRead("0");
            message.setCreateTime(LocalDateTime.now());
            messageMapper.insert(message);
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
    }
    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_UNCOMMITTED, timeout = 30, rollbackFor = Exception.class)
    // 获取两个人的聊天记录
    public List<Message> findMessageBySendUserAndReceiveUser(String sendUserId, String receiveUserId) {
            if(Validator.isEmpty(sendUserId)) throw new BusinessException("发送用户为空!");
            if(Validator.isEmpty(receiveUserId)) throw new BusinessException("接收用户为空!");
            User sendUser = userMapper.selectById(sendUserId);
            if(Validator.isEmpty(sendUser)) throw new BusinessException("发送用户不存在,发送信息失败!");
            User receiveUser = userMapper.selectById(receiveUserId);
            if(Validator.isEmpty(receiveUser)) throw new BusinessException("接收用户不存在,发送信息失败!");
            // 获取对方发送的信息
            QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();
            messageQueryWrapper.lambda().eq(Message::getSendUser,sendUserId)
                    .eq(Message::getReceiveUser,receiveUserId);
            messageQueryWrapper.lambda().last("limit "+limitMessagesLength);
            List<Message> receiveMessageList = messageMapper.selectList(messageQueryWrapper);
            messageQueryWrapper.clear();
            // 获取发送给对方的信息
            messageQueryWrapper.lambda().eq(Message::getSendUser,receiveUserId)
                    .eq(Message::getReceiveUser,sendUserId);
            messageQueryWrapper.lambda().last("limit "+limitMessagesLength);
            List<Message> sendMessageList = messageMapper.selectList(messageQueryWrapper);
            List<Message> allMessageList = new ArrayList<>();
            allMessageList.addAll(receiveMessageList);
            allMessageList.addAll(sendMessageList);
            List<Message> sortedMessageList = allMessageList.stream()
                    .sorted(Comparator.comparing(Message::getCreateTime))
                    .collect(Collectors.toList());

            // 设置已读
            List<Message> noReadMessageList = receiveMessageList.stream()
                    .filter(o -> "0".equals(o.getIsRead()))
                    .peek(message -> message.setIsRead("1"))
                    .collect(Collectors.toList());
            if (noReadMessageList.size() > 0) {
                messageMapper.saveBatch(noReadMessageList);
            }
            return sortedMessageList;
    }

    // 获取所有数据
    public List<MessageForm> findAllMessageForm(String userId) throws Exception {
        try {

            Map<String, WebSocket> users = webSocketUtil.getUsers();
            Set<String> ids = users.keySet();
            if(Validator.isEmpty(userId)) throw new BusinessException("用户编号不能为空!");
            List<MessageForm> messageFormList = new ArrayList<>();
            User loginUser = userMapper.selectById(userId);
            if(Validator.isEmpty(loginUser)) throw new BusinessException("用户编号:" + userId + "不存在!");
            messageFormList.addAll(findAllMessageChatDataWithLoginUserId(userId));
            // 判断ids是否在messageFormList的sendUser的Id中，不是则获取新的数据到messageFormList
            for (String id : ids) {
                if (!messageFormList.stream().map(o -> o.getSendUser().getUserId())
                        .collect(Collectors.toList())
                        .contains(id)) {
                    MessageForm messageForm = new MessageForm();
                    User sendUserData = userMapper.selectById(id);
                    if (null == sendUserData) {
                        continue;
                    }
                    List<Message> allMessageList = findBothMessages(userId, id, limitMessagesLength);
                    messageForm.setMessages(allMessageList);
                    messageForm.setSendUser(sendUserData);
                    messageForm.setReceiveUser(loginUser);
                    messageForm.setIsOnline(true);
                    messageForm.setNoReadMessageLength(0);
                    messageForm.setLastMessage("");
                    messageFormList.add(messageForm);
                }
            }
            // 获取所有messageFormList的sendUser的userId,
            List<String> sendUserIds = messageFormList.stream().map(MessageForm::getSendUser)
                    .map(User::getUserId).collect(Collectors.toList());
            // 如果获取到的用户少于100个，则补齐剩余数量的用户数据,这里补齐的是从没和自己聊天过的用户
//            if (sendUserIds.size() < limitUserLength) {
//                Integer leaveCount = limitUserLength - sendUserIds.size();
//                Where where = new Where();
//                where.notIn("user_id", sendUserIds.toArray());
//                where.limit(leaveCount);
//                List<User> userList = userDao.selectByWhere(where);
//                if (null != userList && userList.size() > 0) {
//                    for (User user : userList) {
//                        MessageForm messageForm = new MessageForm();
//                        messageForm.setSendUser(user);
//                        messageForm.setReceiveUser(loginUser);
//                        messageForm.setIsOnline(false);
//                        messageForm.setNoReadMessageLength(0);
//                        messageForm.setLastMessage("");
//                        messageFormList.add(messageForm);
//                    }
//                }
//            }
            // 按照在线状态为true，有聊天记录的优先展示
            messageFormList.sort((o1, o2) -> {
                if (o1.getIsOnline() && o2.getIsOnline()) {
                    return o2.getMessages().size() - o1.getMessages().size();
                } else if (o1.getIsOnline()) {
                    return -1;
                } else if (o2.getIsOnline()) {
                    return 1;
                } else {
                    return o2.getMessages().size() - o1.getMessages().size();
                }
            });
            return messageFormList;
        } catch (Exception e) {
            throw new Exception(e.getMessage());
        }
    }

    // 获取登录用户所有聊过天的记录数据
    public List<MessageForm> findAllMessageChatDataWithLoginUserId(String userId) {
            Map<String, WebSocket> users = webSocketUtil.getUsers();
            Set<String> ids = users.keySet();
            if(Validator.isEmpty(userId)) throw new BusinessException("用户编号不能为空!");
            List<MessageForm> messageFormList = new ArrayList<>();
            User loginUser = userMapper.selectById(userId);
            if(Validator.isEmpty(loginUser)) throw new BusinessException("用户编号:" + userId + "不存在!");
            // 获取所有有发送信息给自己聊天的用户
            QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();
            messageQueryWrapper.lambda().eq(Message::getReceiveUser,loginUser.getUserId());
            List<Message> list = messageMapper.selectList(messageQueryWrapper);
            List<String> allSendUsers = list.stream().map(Message::getSendUser).distinct().collect(Collectors.toList());
            for (String sendUser : allSendUsers) {
                // 发送人的用户信息
                MessageForm messageForm = new MessageForm();
                User sendUserData = userMapper.selectById(sendUser);
                if (Validator.isEmpty(sendUserData)) {
                    continue;
                }
                // 获取对方发送的信息
                messageQueryWrapper.clear();
                messageQueryWrapper.lambda().eq(Message::getSendUser,sendUser)
                        .eq(Message::getReceiveUser,userId);
                messageQueryWrapper.last("limit "+limitMessagesLength);
                List<Message> receiveMessageList = messageMapper.selectList(messageQueryWrapper);
                // 获取发送给对方的信息
                messageQueryWrapper.clear();
                messageQueryWrapper.lambda().eq(Message::getSendUser,userId)
                        .eq(Message::getReceiveUser,sendUser);
                messageQueryWrapper.last("limit "+limitMessagesLength);
                List<Message> sendMessageList = messageMapper.selectList(messageQueryWrapper);
                List<Message> allMessageList = new ArrayList<>();
                allMessageList.addAll(receiveMessageList);
                allMessageList.addAll(sendMessageList);

                List<Message> sortedMessageList = allMessageList.stream()
                        .sorted(Comparator.comparing(Message::getCreateTime))
                        .collect(Collectors.toList());
                // 赋值最新消息
                messageForm.setLastMessage(
                        sortedMessageList.size() > 0 ? sortedMessageList.get(sortedMessageList.size() - 1)
                                .getContent() : "");
                // 赋值聊天记录
                messageForm.setMessages(sortedMessageList);
                // 赋值未读消息
                messageForm.setNoReadMessageLength(
                        receiveMessageList.stream().filter(o -> "0".equals(o.getIsRead())).collect(
                                Collectors.toList()).size());
                // 赋值发送人
                messageForm.setSendUser(sendUserData);
                // 赋值接收人
                messageForm.setReceiveUser(loginUser);
                // 赋值是否在线
                messageForm.setIsOnline(ids.contains(sendUser));
                messageFormList.add(messageForm);
            }
            // 获取只有自己发送信息给别人的记录的用户
            QueryWrapper<Message> messageQueryWrapper1 = new QueryWrapper<>();
            messageQueryWrapper1.lambda().eq(Message::getSendUser,userId);
            List<String> allSendToUsers = messageMapper.selectList(messageQueryWrapper1).stream().map(Message::getReceiveUser).distinct().collect(Collectors.toList());
            for (String receiveUser : allSendToUsers) {
                // 判断messageFormList的sendUser的userId是否包含receiveUser，有则说明已经存在了
                if (messageFormList.stream()
                        .anyMatch(o -> o.getSendUser().getUserId().equals(receiveUser))) {
                    continue;
                }
                MessageForm messageForm = new MessageForm();
                User receiveUserData = userMapper.selectById(receiveUser);
                if (Validator.isEmpty(receiveUserData)) {
                    continue;
                }
                messageForm.setReceiveUser(loginUser);
                messageForm.setSendUser(receiveUserData);
                messageForm.setLastMessage("");
                messageForm.setNoReadMessageLength(0);
                QueryWrapper<Message> messageQueryWrapper2 = new QueryWrapper<>();
                messageQueryWrapper2.lambda().eq(Message::getSendUser,userId)
                        .eq(Message::getReceiveUser,receiveUser);
                messageQueryWrapper2.last("limit "+limitMessagesLength);
                List<Message> sendMessageList = messageMapper.selectList(messageQueryWrapper2);
                // 按照CreateTime排序从小到大
                messageForm.setMessages(sendMessageList.stream()
                        .sorted(Comparator.comparing(Message::getCreateTime))
                        .collect(Collectors.toList()));
                messageForm.setIsOnline(ids.contains(receiveUser));
                messageFormList.add(messageForm);
            }
            return messageFormList;
    }

    // 用户区查到的数据，有用户名就查用户名对应用户数据和聊天记录，没有默认查300个用户（配置）
    @Override
    public List<MessageForm> searchUserForForm(String userId, String username) {
        try {
            List<MessageForm> messageFormList = new ArrayList<>();
            if(Validator.isEmpty(userId)) throw new BusinessException("登录用户不能为空!");
            User loginUser = userMapper.selectById(userId);
            if(Validator.isEmpty(loginUser)) throw new BusinessException("登录用户不存在!");
            if (Validator.isNotEmpty(username)) {
                QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();
                userQueryWrapper.lambda().like(User::getUserName, StrUtil.format("%{}%",username));
                List<User> userList = userMapper.selectList(userQueryWrapper);
                Map<String, WebSocket> users = webSocketUtil.getUsers();
                Set<String> ids = users.keySet();
                for (User user : userList) {
                    User sendUserData = userMapper.selectById(user.getUserId());
                    if (Validator.isEmpty(sendUserData)) {
                        continue;
                    }
                    MessageForm messageForm = new MessageForm();
                    messageForm.setSendUser(sendUserData);
                    messageForm.setReceiveUser(loginUser);
                    messageForm.setIsOnline(ids.contains(user.getUserId()));
                    // 获取对方发送的信息
                    QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();
                    messageQueryWrapper.lambda().eq(Message::getSendUser,sendUserData.getUserId())
                            .eq(Message::getReceiveUser,loginUser.getUserId());
                    messageQueryWrapper.last("limit "+limitMessagesLength);
                    List<Message> receiveMessageList = messageMapper.selectList(messageQueryWrapper);
                    // 获取发送给对方的信息
                    messageQueryWrapper.clear();
                    messageQueryWrapper.lambda().eq(Message::getSendUser,loginUser.getUserId())
                            .eq(Message::getReceiveUser,sendUserData.getUserId());
                    messageQueryWrapper.last("limit "+limitMessagesLength);
                    List<Message> sendMessageList = messageMapper.selectList(messageQueryWrapper);
                    List<Message> allMessages = new ArrayList<>();
                    allMessages.addAll(receiveMessageList);
                    allMessages.addAll(sendMessageList);
                    allMessages.sort((o1, o2) -> {
                        if (o1.getCreateTime().isBefore(o2.getCreateTime())) {
                            return -1;
                        } else if (o1.getCreateTime().isAfter(o2.getCreateTime())) {
                            return 1;
                        } else {
                            return 0;
                        }
                    });
                    if (allMessages.size() > 0) {
                        messageForm.setLastMessage(allMessages.get(allMessages.size() - 1).getContent());
                    } else {
                        messageForm.setLastMessage("");
                    }
                    messageForm.setMessages(allMessages);
                    // 获取allMessages中isRead为0的数量
                    messageForm.setNoReadMessageLength(
                            (int) allMessages.stream().filter(message -> "0".equals(message.getIsRead()))
                                    .count());
                    messageFormList.add(messageForm);
                }
            } else {
                messageFormList.addAll(findAllMessageForm(userId));
            }
            return messageFormList;
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
    }

    private List<Message> findBothMessages(String sendUserId, String receiveUserId,
                                           Integer limitMessageLength) {
        QueryWrapper<Message> messageQueryWrapper = new QueryWrapper<>();
        messageQueryWrapper.lambda().eq(Message::getSendUser,receiveUserId)
                        .eq(Message::getReceiveUser,sendUserId);
        messageQueryWrapper.last("limit "+limitMessageLength);
        List<Message> receiveMessageList = messageMapper.selectList(messageQueryWrapper);
        messageQueryWrapper.clear();
        messageQueryWrapper.lambda().eq(Message::getSendUser,sendUserId)
                .eq(Message::getReceiveUser,receiveUserId);
        messageQueryWrapper.last("limit "+limitMessageLength);
        List<Message> sendMessageList = messageMapper.selectList(messageQueryWrapper);
        List<Message> allMessageList = new ArrayList<>();
        allMessageList.addAll(receiveMessageList);
        allMessageList.addAll(sendMessageList);
        allMessageList.stream().sorted(Comparator.comparing(Message::getCreateTime))
                .collect(Collectors.toList());
        return allMessageList;
    }
}

